<?php

namespace App\Miya\Models;

use App\Miya\Traits\Scope\OrderByIdTrait;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Route;

class Info extends Model
{
    use OrderByIdTrait;

    protected $guarded = [];

    static public $states = [
        1 => '开启',
        2 => '关闭',
    ];
    protected $casts = [
        'images' => 'json',
        'custom_keywords' => 'json',
        'extends' => 'json',
    ];

    static public $RankByTimeUp = 1;
    static public $RankByTimeDown = 2;
    static public $RankByRankUp = 3;
    static public $RankByRankDown = 4;

    //信息的默认关联关系
    static public $DefaultRelationships = [
        'keyword', 'info_types.module_type', 'module:id,name,tag',
        'classify:id,name,avatar,tag,module_id', 'classify.module:id,name,tag'
    ];

    static public $rankTypes = [
        1 => '发布时间倒叙',
        2 => '发布时间正序',
        3 => '优先级从大到小',
        4 => '优先级从小到大',
    ];

    public function getImagesAttribute($value)
    {
        return array_values(json_decode($value, true) ?: []);
    }

    public function setImagesAttribute($value)
    {
        $this->attributes['images'] = json_encode(array_values($value));
    }

    public function getCustomKeywordsAttribute($value)
    {
        if ($value == '[null]') {
            $value = '[]';
        }
        return array_values(json_decode($value, true) ?: []);
    }

    public function setCustomKeywordsAttribute($value)
    {
        $this->attributes['custom_keywords'] = json_encode(array_values($value), JSON_UNESCAPED_UNICODE);
    }

    public function getExtendsAttribute($value)
    {
        return json_decode($value, true) ?: [];
    }

    public function setExtendsAttribute($value)
    {
        $this->attributes['extends'] = json_encode($value, JSON_UNESCAPED_UNICODE);
    }

    public function module()
    {
        return $this->belongsTo(Module::class);
    }

    public function classify()
    {
        return $this->belongsTo(Classify::class);
    }

    public function info_types()
    {
        return $this->hasMany(InfoType::class);
    }

    public function types()
    {
        return $this->hasMany(InfoType::class, 'info_id');
    }

    public function getTypeListAttribute()
    {
        $data = [];
        foreach ($this->types as $type) {
            if (!$type->module_type) continue;

            $types = collect($type->module_type->values)->pluck('value', 'hash');
            $data[$type->module_type->name] = $types[$type->value];
        }

        return $data;
    }

    public function keyword()
    {
        return $this->belongsTo(Keyword::class);
    }

    // 信息展示时间
    public function getTimeAttribute()
    {
        if ($this->is_delayed == 2) {
            return $this->created_at;
        }

        return Carbon::parse($this->delayed_at);
    }

    public function url($derivative = null)
    {
        $current = Route::currentRouteName();
        $prefix = explode('.', $current)[0];
        $data = [$this->module->tag, $this->classify->tag, $this->tag];
        if ($derivative) {
            $data[] = urlencode($derivative);
        }
        $routeName = null;
        switch ($prefix) {
            case 'pc':
                $routeName = $derivative ? 'pc.derivative' : 'pc.info';
                break;
            case 'area':
                $area = request()->route('area');
                $data = Arr::collapse([[$area->tag], $data]);
                $routeName = $derivative ? 'area.derivative' : 'area.info';
                break;
            case 'm':
                $routeName = $derivative ? 'm.derivative' : 'm.info';
                break;
            case 'domain_area':
                $area = request()->route('area');
                $data = Arr::collapse([[$area->tag], $data]);
                $routeName = $derivative ? 'domain_area.derivative' : 'domain_area.info';
                break;
            default:
                $routeName = 'pc.info';
                break;
        }
        return route($routeName, $data);
    }

    public function sketch($limit = 100)
    {
        return Str::limit(strip_tags($this->content), $limit);
    }

    public function getKeywords()
    {
        if (!$this->keyword) {
            return $this->custom_keywords;
        } else {
            return Arr::collapse([$this->custom_keywords, [$this->keyword->keyword]]);
        }
    }

    public function parseTime($format = 'Y-m-d H:i:s')
    {
        if ($this->is_delayed == 2) {
            $time = $this->created_at;
        } else {
            $time = $this->delayed_at;
        }

        return Carbon::parse($time)->format($format);
    }

    static public function rankByType($query, $rank_type = 1)
    {
        $query->withoutGlobalScope('id');
        switch ($rank_type) {
            case Info::$RankByTimeUp:
                $query->orderBy('id', 'DESC')->orderBy('delayed_at', 'DESC');
                break;
            case Info::$RankByTimeDown:
                $query->orderBy('delayed_at')->orderBy('id');
                break;
            case Info::$RankByRankUp:
                $query->orderBy('rank', 'DESC');
                break;
            case Info::$RankByRankDown:
                $query->orderBy('rank');
                break;
        }

        return $query;
    }
}
